/*
 * XActionLabel.java
 * 
 * Copyright (c) 2006 - 2007
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xfc.components;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;

import org.xfc.util.XListenerManager;

import com.jgoodies.forms.layout.FormLayout;

/**
 * A hyperlink component.
 * 
 * @author Devon Carew
 */
public class XActionLabel
	extends JComponent
{
	private JLabel 	label;
	private Action	action;
	
	private XListenerManager listenerManager = new XListenerManager();
	
	private Color	LINK_COLOR = Color.BLUE;
	private Color	PRESSED_COLOR = Color.RED.brighter();
	private Color	DISABLED_COLOR;
	
	private boolean	pressed;
	private String	actionCommand;
	
	public XActionLabel()
	{
		// Create a JLabel that draws a line under the text.
		label = new JLabel() {
			protected void paintComponent(Graphics g) {
				super.paintComponent(g);
				
				if (!isEnabled())
					g.setColor(Color.LIGHT_GRAY);
				
				g.drawLine(0, getHeight() - 1, getWidth() - 1, getHeight() - 1);
			}
		};
		
		DISABLED_COLOR = label.getForeground();
		
		setOpaque(false);
		
		setLayout(new FormLayout("pref:grow", "pref:grow"));
		add(label, "1, 1, l, c");
		
		label.addMouseListener(new MouseListener() {
			public void mouseEntered(MouseEvent event) {
				if (isEnabled())
					label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
			}
			public void mouseExited(MouseEvent event) {
				label.setCursor(Cursor.getDefaultCursor());
			}
			
			public void mousePressed(MouseEvent event) {
				if (isEnabled()) {
					pressed = true;
					updateLabel();
				}
			}
			public void mouseReleased(MouseEvent event) {
				pressed = false;
				updateLabel();
			}
			
			public void mouseClicked(MouseEvent event) {
				fireActionPerformed();
			}
		});
		
		updateLabel();
	}
	
	public XActionLabel(String text)
	{
		this();
		
		setText(text);
	}
	
	public XActionLabel(Action action)
	{
		this();
		
		this.action = action;
		
		if (action.getValue(Action.NAME) != null)
			setText((String)action.getValue(Action.NAME));
		
		if (action.getValue(Action.SMALL_ICON) != null)
			setIcon((Icon)action.getValue(Action.SMALL_ICON));
		
		if (action.getValue(Action.SHORT_DESCRIPTION) != null)
			setToolTipText((String)action.getValue(Action.SHORT_DESCRIPTION));
	}
	
	/**
	 * @see JLabel#getDisabledIcon()
	 * @return the disabled icon
	 */
	public Icon getDisabledIcon()
	{
		return label.getDisabledIcon();
	}
	
	/**
	 * @param icon
	 */
	public void setDisabledIcon(Icon icon)
	{
		label.setDisabledIcon(icon);
	}
	
	/**
	 * @return Returns the horizontal position of the label's text, relative to its image.
	 */
	public int getHorizontalTextPosition()
	{
		return label.getHorizontalTextPosition();
	}
	
	/**
	 * @param textPosition
	 */
	public void setHorizontalTextPosition(int textPosition)
	{
		label.setHorizontalTextPosition(textPosition);
	}
	
	/**
	 * @return Returns the action label's icon.
	 */
	public Icon getIcon()
	{
		return label.getIcon();
	}
	
	/**
	 * @param icon
	 */
	public void setIcon(Icon icon)
	{
		label.setIcon(icon);
	}
		
	/**
	 * @return Returns the action label's text.
	 */
	public String getText()
	{
		return label.getText();
	}
	
	/**
	 * @param text
	 */
	public void setText(String text)
	{
		label.setText(text);
	}
	
	/** {@inheritDoc} */
	public void setToolTipText(String tooltip)
	{
		super.setToolTipText(tooltip);
		
		label.setToolTipText(tooltip);
	}
	
	/** {@inheritDoc} */
	public void setEnabled(boolean enabled)
	{
		super.setEnabled(enabled);
		
		label.setEnabled(enabled);
		
		updateLabel();
	}

	public void addActionListener(ActionListener listener)
	{
		listenerManager.addListener(listener);
	}
	
	public void removeActionListener(ActionListener listener)
	{
		listenerManager.removeListener(listener);
	}
	
	public String getActionCommand()
	{
		return actionCommand;
	}
	
	public void setActionCommand(String actionCommand)
	{
		this.actionCommand = actionCommand;
	}
	
	private void updateLabel()
	{
		if (isEnabled())
		{
			if (pressed)
			{
				label.setForeground(PRESSED_COLOR);
			}
			else
			{
				label.setForeground(LINK_COLOR);
			}
		}
		else
		{
			label.setForeground(DISABLED_COLOR);
		}
		
		repaint();
	}
	
	private void fireActionPerformed()
	{
		if (!isEnabled())
			return;
		
		ActionEvent event = new ActionEvent(this, 0, getActionCommand());
		
		listenerManager.notifyListeners("actionPerformed", event);
		
		if (action != null)
			action.actionPerformed(event);
	}
	
}
